﻿using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Fee;
using Fee.FileAttachs;
using Fee.Orders;
using Fee.Orders.AuthProjectWorkflow;
using Fee.Searchers;
using Fee.Stores;
using Identity;
using JwtWebApi.Data;
using JwtWebApi.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace JwtWebApi.Controllers
{
    [Authorize]
    [Route("[controller]")]
    [ApiController]
    [EnableCors]
    public class ConstructionTaskController : Controller
    {
        private readonly IConstructionTaskStore<ApplicationDbContext> _constructionTaskStore;
        private readonly ApplicationDbContext _dbContext;
        private readonly FileManager _fileManager;

        public ConstructionTaskController(IConstructionTaskStore<ApplicationDbContext> constructionTaskStore,
            ApplicationDbContext dbContext, FileManager fileManager)
        {
            _constructionTaskStore = constructionTaskStore;
            _dbContext = dbContext;
            _fileManager = fileManager;
        }

        [HttpGet("list")]
        public IActionResult Index([FromQuery] ConstructionTaskSearcher searcher)
        {
            var data = _constructionTaskStore.List(searcher, out var total);
            return Json(new
            {
                data,
                total
            });
        }

        [HttpGet("getByStation/{id:int}")]
        public IActionResult GetByStation([FromRoute]int id)
        {
            var re = _constructionTaskStore.GetByStation(id);
            return Ok(re);
        }

        [HttpGet("get/{id:int}")]
        public IActionResult Get(int id)
        {
            var ad = _constructionTaskStore.Get(id);
            return Json(ad);
        }

        [HttpDelete("attach/{taskId:int}/{fileAttachId:int}")]
        public IActionResult DeleteAttach
        ([FromRoute] int fileAttachId, [FromRoute] int taskId
        )
        {
            var order
                = _dbContext.Set<ConstructionTask>().Include(_ => _.Attaches).ThenInclude(_ => _.File.UploadUser)
                    .FirstOrDefault(f => f.Id == taskId);

            for (var index = 0; index < order.Attaches.Count; index++)
            {
                var attach = order.Attaches[index];
                if (attach.FileId == fileAttachId)
                {
                    System.IO.File.Delete(order.Attaches[index].File.SystemPath);
                    order.Attaches.RemoveAt(index);
                    break;
                }
            }

            _dbContext.SaveChanges();
            return Json(new
            {
                success = true,
                message = "删除成功"
            });
        }

        [HttpPost("attach/{id:int}")]
        public async Task<IActionResult> UploadAttach([FromRoute] int id
            , [FromForm] IFormFile formFile)
        {
            var filePath = _fileManager.GetAuthProjectFileTask(Path.GetExtension(formFile.FileName), id);

            var stream = new FileStream(filePath, FileMode.Create);


            var copyTask = formFile.CopyToAsync(stream).ContinueWith(task =>
            {
                stream.Dispose();

            });


            var attach = new FileAttach(formFile.FileName, filePath)
            {
                UploadUser = _dbContext.GetByUserName(this.User.Identity.Name)
            };

            var order
                = _dbContext.Set<ConstructionTask>().Include(_ => _.Attaches).ThenInclude(_ => _.File.UploadUser)
                    .FirstOrDefault(f => f.Id == id);

            order.Attaches.Add(new ConstructionTaskFileAttach()
            {
                File = attach,
                Task = order
            });
            await copyTask;
            _dbContext.SaveChanges();
            return Json(new
            {
                successed = true
            });
        }
        [HttpGet("attach/{orderId:int}")]
        public IActionResult ListAttach([FromRoute] int orderId)
        {
            var attaches
                = _dbContext.Set<ConstructionTask>()
                    .Include(_ => _.Attaches).ThenInclude(_ => _.File).ThenInclude(f => f.UploadUser)


                    .Where(f => f.Id == orderId).SelectMany(f => f.Attaches).Select(_ => new
                    {
                        _.File.Id,
                        _.File.CreateTime,
                        _.File.Name,
                        Uploader = _.File.UploadUser != null ? _.File.UploadUser.Name : "",

                    });


            return Json(attaches);
        }
        [HttpGet("attach/{id:int}/{fileAttachId:int}")]
        public IActionResult GetBlobDownload([FromRoute]int fileAttachId, [FromRoute]int id)
        {
            var file = _dbContext.Set<FileAttach>().FirstOrDefault(f => f.Id == fileAttachId);

            var filePath = file.SystemPath;
            var contentType = "application/octet-stream";
            var fileName = file.Name;
            return File(System.IO.File.OpenRead(filePath), contentType, fileName);
        }

        [HttpGet("formal-station-list")]
        public IActionResult ListComplate([FromQuery]FormalVendorSearcher pager)
        {
            var user = _dbContext.GetByUserName(this.User.Identity.Name);

            _dbContext.Entry(user).Reference(f => f.Vendor).Load();

            var vendor = user.Vendor != null ? user.Vendor : default(Vendor);


         
            IQueryable<ConstructionTask> query;
            if (vendor != null)
            {
                var taskId = _dbContext.Set<ConstructionDetail>()
                    .Where(f => f.Contract.Vendor == vendor)
                    .Select(f => f.TaskId).Distinct();

                query = from task in _dbContext.Set<ConstructionTask>()
                        .Include(_ => _.Station).ThenInclude(f => f.District)
                        .Include(_ => _.Station).ThenInclude(f => f.OrderDistrict)

                    where task.Status == ConstructionTaskStatus.FormalAuthed && taskId.Contains(task.Id)

                    select task;
            }
            else
            {
                query= from task in _dbContext.Set<ConstructionTask>()
                        .Include(_ => _.Station).ThenInclude(f => f.District)
                        .Include(_ => _.Station).ThenInclude(f => f.OrderDistrict)

                    where task.Status == ConstructionTaskStatus.FormalAuthed 

                    select task;
            }

            var total = query.Count();
            return Json(new
            {
                total = total,
                data = query.Take(pager.GetTake()).Skip(pager.GetSkip())
            });

        }

    }
}